package org.indrio.pingfm.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.log4j.Logger;
import org.indrio.pingfm.ServerRequest;
import org.indrio.pingfm.ServerResponse;
import org.indrio.pingfm.XMLResultParser;
import org.indrio.pingfm.beans.Service;
import org.indrio.pingfm.beans.Trigger;

public class ServerRequestImpl implements ServerRequest{

	private final Logger LOGGER = Logger.getLogger(ServerRequest.class);

	HttpClient httpClient = new HttpClient();
	
	public ServerResponse send(String _host, String _path, Map<String, String> _params) throws IOException{
		LOGGER.debug("entering send method");
		LOGGER.debug("	> _host : "+_host);
		LOGGER.debug("	> _path : "+_path);
		LOGGER.debug("	> _params : ");

		for(Map.Entry<String, String> entry: _params.entrySet()) {
			LOGGER.debug("		> "+entry.getKey()+" : "+entry.getValue());
		}
		
		PostMethod postMethod = new PostMethod(_path);
		
		httpClient.getHostConfiguration().setHost(_host, 80, "http");
		
		postMethod.setRequestBody(genNameValuePair(_params));
		
		httpClient.executeMethod(postMethod);
		
		InputStream responseBody = postMethod.getResponseBodyAsStream(); 

		ServerResponse serverResponse = convertToServerResponse(responseBody);
		
		postMethod.releaseConnection();
		
		return serverResponse;
	}
	
	private NameValuePair[] genNameValuePair(Map<String, String> _params) {
		LOGGER.debug("create params ");
		
		NameValuePair[] nameValuePair = new NameValuePair[_params.size()];
		
		int i = -1;
		for(Map.Entry<String, String> entry: _params.entrySet()) {
			nameValuePair[++i] = new NameValuePair(entry.getKey(), entry.getValue());
		}
		
		return nameValuePair;
	}
	
	private ServerResponse convertToServerResponse(InputStream _responseStream) {
		XMLResultParser parser = new XMLResultParser(_responseStream);
		
		ServerResponse serverResponse = new ServerResponse(parser.getStatus(), parser.getTransactionId(), parser.getMethod(), parser.getErrorMessage());
		
		LOGGER.debug("status : "+serverResponse.getStatus());
		LOGGER.debug("transactionId : "+serverResponse.getTransactionId());
		LOGGER.debug("method : "+serverResponse.getMethod());
		LOGGER.debug("error message : "+serverResponse.getErrorMessage());
		
		if(parser.getServices() != null) {
			serverResponse.setService(parser.getServices());
			
			for(Service service : serverResponse.getService()) {
				LOGGER.debug("service : ");
				LOGGER.debug("	> id : "+service.getId());
				LOGGER.debug("	> name : "+service.getName());
				LOGGER.debug("	> trigger : "+service.getTrigger());
				LOGGER.debug("	> url : "+service.getUrl());
				LOGGER.debug("	> icon : "+service.getIcon());
				LOGGER.debug("	> methods : "+service.getMethods());
			}
		}
		
		if(parser.getTrigger() != null) {
			serverResponse.setTrigger(parser.getTrigger());
	
			for(Trigger trigger : serverResponse.getTrigger()) {
				LOGGER.debug("trigger : ");
				LOGGER.debug("	> id : "+trigger.getId());
				LOGGER.debug("	> method : "+trigger.getMethod());
			}
		}
		
		if(parser.getMessages() != null) {
			serverResponse.setMessages(parser.getMessages());
		}
		
		return serverResponse;
	}
}
